﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AirConditionControl.Controls
{
    public partial class UButton : UserControl
    {

        public UButton()
        {
            InitializeComponent();

            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(ControlStyles.Selectable, true);

            this.Size = new Size(100, 40);
            this.Cursor = Cursors.Hand;
            this.BackColor = Color.Transparent;
            this.Font = new Font("微软雅黑", 9, FontStyle.Bold);
            this.AutoSize = true;
            Click += UButton_Click;
        }

        private void UButton_Click(object? sender, EventArgs e)
        {
            IsCheck = !IsCheck;
        }

        private string content = "已关闭";

        // 按钮是否选中
        private bool isCheck = false;
        [Category("自定义属性")]
        [Description("按钮是否选中")]
        public bool IsCheck
        {
            get { return isCheck; }
            set
            {
                isCheck = value;
                if (isCheck)
                {
                    content = "已开启";
                }
                else
                {
                    content = "已关闭";
                }
                Invalidate();
            }
        }

        private Color onColor = Color.LimeGreen;

        public Color OnColor
        {
            get { return onColor; }
            set
            {
                onColor = value;
                Invalidate();
            }
        }

        private Color offColor = Color.Gray;

        public Color OffColor
        {
            get { return offColor; }
            set
            {
                offColor = value;
                Invalidate();
            }
        }

        private int border = 3;
        private Color borderColor = Color.DarkGray;


        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g.Clear(this.Parent.BackColor);

            Rectangle workingArea = ClientRectangle;

            Rectangle rect = new Rectangle();
            rect.X = workingArea.X + border;
            rect.Y = workingArea.Y + border;
            rect.Width = workingArea.Width - 2 * border;
            rect.Height = workingArea.Height - 2 * border;

            GraphicsPath boxPath = GetRoundPath(rect);

            Color backColor;

            if (isCheck)
            {
                backColor = onColor;
                SolidBrush backBrush = new SolidBrush(backColor);
                g.FillPath(backBrush, boxPath);

                SolidBrush borderBrush = new SolidBrush(borderColor);
                g.DrawPath(new Pen(borderBrush, border), boxPath);
                DrawOpen(rect,g);
            }
            else
            {
                backColor = offColor;
                SolidBrush backBrush = new SolidBrush(backColor);
                g.FillPath(backBrush, boxPath);

                SolidBrush borderBrush = new SolidBrush(borderColor);
                g.DrawPath(new Pen(borderBrush, border), boxPath);
                DrawClose(rect, g);
            }         
        }

        private void DrawOpen(Rectangle rect,Graphics g)
        {
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Near;
            format.LineAlignment = StringAlignment.Center;

            g.DrawString(content, this.Font, new SolidBrush(Color.White), new Rectangle(rect.X + rect.Height / 2, rect.Y, rect.Width - rect.Height, rect.Height), format);

            // 大圆
            int d = rect.Height - 6;
            int rx = rect.Width - d - 2;
            int ry = rect.Y + 3;
            g.FillEllipse(new SolidBrush(Color.White), new Rectangle(rx, ry, d, d));

            // 小圆
            int dd = d - 8;
            int rrx = rx + 4;
            int rry = ry + 4;
            LinearGradientBrush linearBrush = new LinearGradientBrush(new Rectangle(rrx, rry, dd, dd), Color.Gray, Color.White, LinearGradientMode.Vertical);
            g.FillEllipse(linearBrush, new Rectangle(rrx, rry, dd, dd));
        }

        private void DrawClose(Rectangle rect, Graphics g)
        {
            StringFormat format = new StringFormat();
            format.Alignment = StringAlignment.Near;
            format.LineAlignment = StringAlignment.Center;

            g.DrawString(content, this.Font, new SolidBrush(Color.White), new Rectangle(rect.X + rect.Height, rect.Y, rect.Width - rect.Height / 2, rect.Height), format);

            // 大圆
            int d = rect.Height - 6;
            int rx = rect.X + 2;
            int ry = rect.Y + 3;
            g.FillEllipse(new SolidBrush(Color.White), new Rectangle(rx, ry, d, d));

            // 小圆
            int dd = d - 8;
            int rrx = rx + 4;
            int rry = ry + 4;
            LinearGradientBrush linearBrush = new LinearGradientBrush(new Rectangle(rrx, rry, dd, dd), Color.Gray, Color.White, LinearGradientMode.Vertical);
            g.FillEllipse(linearBrush, new Rectangle(rrx, rry, dd, dd));
        }


        private GraphicsPath GetRoundPath(Rectangle rect)
        {
            GraphicsPath path = new GraphicsPath();
            int x = rect.X;
            int y = rect.Y;
            int w = rect.Width;
            int h = rect.Height;

            // 左半圆
            path.AddArc(new Rectangle(x, y, h, h), 90f, 180f);
            // 上边线
            path.AddLine(h / 2, y, w - h / 2, y);
            // 右半圆
            path.AddArc(new Rectangle(w - h, y, h, h), 270f, 180f);
            // 下边线
            path.AddLine(w - h / 2, y + h, h / 2, y + h);

            return path;
        }
    }
}
